import { Vector2, ColorUtil, Vector2Util } from './../utils';
import { BaseCanvas } from '../base/baseCanvas';
import { IShape } from './../model';

interface BallOption {
    x: number;
    y: number;
    radius: number;
    velocity: Vector2;
    color?: string;
}

export class Ball extends BaseCanvas {

    position!: Vector2;
    velocity!: Vector2;
    color!: string;
    radius!: number;
    id = ColorUtil.getRandom();

    constructor(canvasEle: HTMLCanvasElement, options: BallOption) {
        super(canvasEle);
        this.position = new Vector2(options.x, options.y);
        this.radius = options.radius;
        this.velocity = options.velocity;
        this.color = options.color ?? ColorUtil.getRandomColor();

    }

    // update(balls: Ball[]) {
    //     const { width, height } = this.canvasEle;
    //     const nextPosition = this.position.add(this.velocity);
    //     const { x, y } = nextPosition;
    //     if (x + this.radius > width || this.radius > x) {
    //         this.velocity.x = -this.velocity.x;
    //     }
    //     if (y + this.radius > height || this.radius > y) {
    //         this.velocity.y = -this.velocity.y;
    //     }
    //     balls.forEach((ball) => {
    //         if (this.id !== ball.id && this.checkIsCollisionPosition(ball)) {
    //             this.collisionAction(ball);
    //         }
    //     });
    //     this.position = this.position.add(this.velocity);
    // }

    render() {
        const ctx = this.ctx;
        ctx.beginPath();
        ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
        ctx.fillStyle = this.color;
        ctx.fill();
    }

    checkIsCollisionPosition(ball: Ball): boolean {
        return this.position.add(this.velocity).subtract(ball.position.add(ball.velocity)).length() <= this.radius + ball.radius;
    }

    collisionAction(ball: Ball) {
        const currentNormalLine = this.position.subtract(ball.position).unitVector();
        const currentInverse = currentNormalLine.inverseVector();
        // reflected is normal line
        // this.velocity = currentNormalLine.multiply(Math.abs(ball.velocity.dotMultiply(currentNormalLine)));
        // ball.velocity = currentInverse.multiply(Math.abs(this.velocity.dotMultiply(currentNormalLine)));
        // reflected is reflect line
        this.velocity = Vector2Util.getReflected(this.velocity, currentNormalLine);
        ball.velocity = Vector2Util.getReflected(ball.velocity, currentInverse);
    }
}

